home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / pas2c.zip / PASOBJ.C < prev    next >
Text File  |  1993-01-04  |  8KB  |  250 lines

  1. /*
  2.  
  3.     PASOBJ.C
  4.  
  5.     Convert OBJ file for use with Turbo Pascal V4.0
  6.  
  7.     The idea is to catch the LNAMES directive in the OBJ file, and
  8.     translate it. BSS, CODE and DATA are class names, and are cleared.
  9.     _TEXT, _DATA and _BSS are segment names, and are converted to
  10.     CSEG, CONST and DSEG respectively. DGROUP is the name of the DATA
  11.     group, and is cleared. All other records are copied verbatim.
  12.  
  13.     All Identifiers in PUBLIC and EXTERNAL declarations are checked to
  14.     see if they have an '@' sign in the name. If an '@' sign is found,
  15.     the '@' is converted to an underscore '_'. This is to allow C
  16.     intrinsic functions to be used.
  17.  
  18.     If a segment identifier matches the name xxx_TEXT, then it is
  19.     converted to CSEG. Note that this happens when Turbo C Large Model
  20.     code is being imported. Specifically, for "shared" library code.
  21.     Remember that any procedures brought in this way MUST be declared
  22.     with {$F+} switch.
  23.  
  24.     Compile with Turbo C, small model, no floating point.
  25.  
  26.  */
  27.  
  28. #include <std.h>
  29. #include <conio.h>
  30. #include <dos.h>
  31. #include <process.h>
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35.  
  36. LOCAL COUNT chksum;
  37.  
  38. LOCAL FILE *Inf, *Outf;
  39.  
  40. LOCAL COUNT Chr, Siz;
  41.  
  42. LOCAL VOID poll(VOID)
  43.     {
  44.     if (bdos(6, 255, 0) == 3)
  45.         exit(7);
  46.     }
  47.  
  48. LOCAL COUNT getch(VOID)                /* get byte from Inf, polling */
  49.     {
  50.     poll();
  51.     --Siz;
  52.     return (getc(Inf));
  53.     }
  54.  
  55. LOCAL COUNT getwd(VOID)                /* get word from Inf, polling */
  56.     {
  57.     poll();
  58.     Siz -= 2;
  59.     return (getw(Inf));
  60.     }
  61.  
  62. LOCAL TEXT *donam(VOID)                /* copy name from record */
  63.     {
  64.     COUNT n;
  65.     TEXT *t, *t1;
  66.  
  67.     n = getch();                       /* number of chars in name */
  68.     t1 = t = malloc(n + 1);            /* get space for it */
  69.     while (n--)
  70.         {
  71.         *t++ = getch();                /* save the name for use */
  72.         }
  73.     *t = 0;
  74.     return (t1);
  75.     }
  76.  
  77. LOCAL VOID outbyte(TEXT c)
  78.     {
  79.     c &= 0xFF;
  80.     chksum += c;
  81.     putc(c, Outf);
  82.     }
  83.  
  84. LOCAL VOID outstring(TEXT *s)
  85.     {
  86.     COUNT n;
  87.  
  88.     n = strlen(s);
  89.     outbyte(n);
  90.     while (n--)
  91.         outbyte(*s++);
  92.     }
  93.  
  94. LOCAL VOID dofile(VOID)
  95.     {
  96.     TEXT *s, *t;
  97.     COUNT newsize, nstrings, i;
  98.     TEXT *strings[100];
  99.     COUNT si, gi;
  100.  
  101.     while ((Chr = getch()) != EOF)
  102.         {
  103.         if (Chr && (Siz = getwd()) > 0) /* skip over null fill */
  104.             {
  105.             switch (Chr)
  106.                 {
  107.                 case 0x96:             /* LNAMES */
  108.                     newsize = 1;
  109.                     nstrings = 0;
  110.                     while (Siz > 1)
  111.                         {
  112.                         s = donam();
  113.                         if (strcmp(s, "CODE") == 0)
  114.                             s = "";
  115.                         if (strcmp(s, "DATA") == 0)
  116.                             s = "";
  117.                         if (strcmp(s, "BSS") == 0)
  118.                             s = "";
  119.                         if (strcmp(s, "_TEXT") == 0)
  120.                             s = "CSEG";
  121.                         if (strcmp(s, "_DATA") == 0)
  122.                             s = "CONST";
  123.                         if (strcmp(s, "_BSS") == 0)
  124.                             s = "DSEG";
  125.                         if (strcmp(s, "DGROUP") == 0)
  126.                             s = "";
  127.                         if ((strlen(s) > 5) &&
  128.                             (strcmp(s + strlen(s) - 5, "_TEXT") == 0))
  129.                             s = "CSEG";
  130.                         newsize += strlen(s) + 1;
  131.                         strings[nstrings++] = s;
  132.                         }
  133.                     getch(); /* skip the original checksum byte */
  134.                     chksum = 0;
  135.                     outbyte(Chr);
  136.                     outbyte(newsize & 0xFF);
  137.                     outbyte((newsize >> 8) & 0xFF);
  138.                     for (i = 0; i < nstrings; ++i)
  139.                         outstring(strings[i]);
  140.                     chksum = -chksum;
  141.                     outbyte(chksum & 0xFF);
  142.                     continue;
  143.  
  144.                 case 0x8C:             /* EXTDEF */
  145.                     chksum = 0;
  146.                     outbyte(Chr);
  147.                     outbyte(Siz & 0xFF);
  148.                     outbyte((Siz >> 8) & 0xFF);
  149.                     while (Siz > 1)
  150.                         {
  151.                         s = donam();
  152.                         for (t = s; *t; ++t)
  153.                             if (*t == '@')
  154.                                 *t = '_';
  155.                         outstring(s);
  156.                         outbyte(getch());
  157.                         }
  158.                     getch(); /* skip the original checksum byte */
  159.                     chksum = -chksum;
  160.                     outbyte(chksum & 0xFF);
  161.                     continue;
  162.  
  163.                 case 0x90:             /* PUBDEF */
  164.                     chksum = 0;
  165.                     outbyte(Chr);
  166.                     outbyte(Siz & 0xFF);
  167.                     outbyte((Siz >> 8) & 0xFF);
  168.                     outbyte(si = getch());
  169.                     outbyte(gi = getch());
  170.                     if (si | gi)
  171.                         ;
  172.                     else
  173.                         {
  174.                         outbyte(getch());
  175.                         outbyte(getch());
  176.                         }
  177.                     while (Siz > 1)
  178.                         {
  179.                         s = donam();
  180.                         for (t = s; *t; ++t)
  181.                             if (*t == '@')
  182.                                 *t = '_';
  183.                         outstring(s);
  184.                         outbyte(getch());
  185.                         outbyte(getch());
  186.                         outbyte(getch());
  187.                         }
  188.                     getch(); /* skip the original checksum byte */
  189.                     chksum = -chksum;
  190.                     outbyte(chksum & 0xFF);
  191.                     continue;
  192.                 }
  193.             outbyte(Chr);
  194.             outbyte(Siz & 0xFF);
  195.             outbyte((Siz >> 8) & 0xFF);
  196.             while (Siz)
  197.                 outbyte(getch());
  198.             }
  199.         }
  200.     }
  201.  
  202. VOID main (COUNT argc, TEXT *argv[])
  203.     {
  204.     TEXT *inname;
  205.  
  206.     printf("PASOBJ 1.00A                            " __DATE__ "\n"
  207.            "Written by Martin Weigel                   76237,733\n"
  208.     if (argc < 2 || argc > 3)
  209.         {
  210.         printf("\nusage: pasobj <infile> [<outfile>]\n\n"
  211.                "PASOBJ converts an OBJ file produced by Turbo C, Compact Model,\n"
  212.                "into an OBJ file suitable for inclusion into a Turbo Pascal 4.0\n"
  213.                "program via the $L directive. The .OBJ extension must be used on\n"
  214.                "both the input and output files. If the outfile is not specified,\n"
  215.                "the infile will be converted to a file of the same name.\n\n");
  216.         exit(1);
  217.         }
  218.     inname = * ++argv;
  219.     if ((Inf = fopen(inname, "rb")) == NIL)
  220.         {
  221.         printf("file <%s> could not be opened\n", *argv);
  222.         exit(1);
  223.         }
  224.     if (argc == 3)
  225.         {
  226.         if ((Outf = fopen(* ++argv, "wb")) == NIL)
  227.             {
  228.             printf("file <%s> could not be created\n", *argv);
  229.             exit(1);
  230.             }
  231.         }
  232.     else
  233.         {
  234.         if ((Outf = fopen("PO$$$.$$$", "wb")) == NIL)
  235.             {
  236.             printf("could not create temporary file\n");
  237.             exit(1);
  238.             }
  239.         }
  240.     dofile();
  241.     fclose(Inf);
  242.     fclose(Outf);
  243.     if (argc == 2)
  244.         {
  245.         unlink(inname);
  246.         rename("PO$$$.$$$", inname);
  247.         }
  248.     exit(0);
  249.     }
  250.